<?php
namespace app\common\model;

use think\Model;

class Category extends Model
{
    /**
     * 添加分类
     * @param $data
     * @param null $where
     * @return mixed
     */
    public function save_category($data, $where = null) {
        if ($data['pid'] > 0) {
            $p_cate = $this->get($data['pid']);
            $level = $p_cate->level + 1;
        } else {
            $level = 1;
        }
        $data['level'] = $level;
        $this->save($data, $where);
        return $this->id;
    }
    /**
     * 获取分类数
     * @return array
     */
    public function get_category_tree() {
        if (!$tree = cache('category_tree')) {
            $cate = $this->all();
            if($cate) {
                foreach ($cate as $item) {
                    $tmpMap[$item['id']] = $item;
                }
                foreach ($cate as $item) {
                    if (isset($tmpMap[$item['pid']])) {
                        $tmpMap[$item['pid']]['childrens'][] = &$tmpMap[$item['id']];
                    }
                    else {
                        $tree[] = &$tmpMap[$item['id']];
                    }
                }
            } else {
                $tree = [];
            }
            cache('category_tree', $tree);
        }
        return $tree;
    }

    /**
     * 根据上级ID获取正常分类信息
     * @param int $pid
     * @return false|static[]
     */
    public function get_category_by_pid($pid = 0) {
        $where = [
            'pid' => $pid
        ];
        $cate = $this->where($where)
            ->order('status', 'desc')
            ->select();
        return $cate;
    }

    /**
     * 根据上级ID获取所有下级分类，并且按级别分组
     * @param int $pid
     * @param int $level
     * @param int $noid
     * @return array
     */
    public function get_category_all($pid = 0, $level = 0, $noid = 0) {
    //根据pid(上级分类ID)取出后代， 并且给每一代分类定义好级别
        static $res = [];// static 定义函数内部的全局变量; 当函数内部调用该函数本身时，所得数据需要该定义才能追加保存到同一变量；
        $data = $this->where('pid', $pid)->where('id', 'neq', $noid)->select();
        //print_r($data);die;
        foreach($data as $v)
        {
            $v['level'] = $level;	//记录级别
            $res[] = $v;
            $this->get_category_all($v['id'], $level+1, $noid);	//函数内部调用该函数本身
        }

        return $res;
    }

    /**
     * 获取分类列表面包屑
     * @param $id
     * @return string
     */
    public function get_category_crumbs_by_pid($id) {
        static $crumbs = [];
        if ($id > 0) {
            $cate = $this->get($id);
            array_unshift($crumbs, '<li><a href="'. url('index', ['id' => $id]) .'">'.$cate['cate_name'] . '</a></li>');
            $this->get_category_crumbs_by_pid($cate['pid']);
        }
        return implode($crumbs, '');
    }

    /**
     * 根据ID删除分类
     * @param $id
     * @return false|int
     */
    public function delete_category_by_id($id) {
        // 删除所有下级分类
        $cate_ids = $this->get_category_all_by_pid($id);
        $cate_ids[] = $id;
        // 删除当前分类
        $this->save(['status' => 0], ['id' => ['in', $cate_ids]]);
        // 删除对应的产品
        model('Product')->save(['status' => 0], ['cate_id' => ['in', $cate_ids]]);
        return true;
    }

    /**
     * 根据上级ID获取下级分类
     * @param $id
     * @return array
     */
    public function get_category_all_by_pid($id) {
        $cate = $this->all(['pid' => $id]);
        static $res = [];// static 定义函数内部的全局变量; 当函数内部调用该函数本身时，所得数据需要该定义才能追加保存到同一变量；
        if ($cate) {
            foreach($cate as $v)
            {
                $res[] = $v['id'];
                $this->get_category_all_by_pid($v['id']);
            }
        }
        //$this->save(['status' => 0], ['id' => ['in', $res]]);
        return $res;
    }

    /**
     * 修改分类状态
     * @param $id
     * @param $pid
     * @return bool
     * @throws \Exception
     */
    public function edit_status_category($id, $pid) {
        // 检查上级分类是否正常
        if ($pid > 0) {
            $cate = $this->get($pid);
            if ($cate['status'] != 1) {
                throw new \Exception('上级分类已删除，请先恢复上级分类状态');
            }
        }

        // 修改当前分类状态
        $this->save(['status' => 1], ['id' => $id]);
        return true;
    }
}
